/*->c.vtlo */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"
#include "h.flex"


#include "h.def"

#include "h.wos"
#include "h.main"
#include "h.ram"
#include "h.mym"
#include "h.trans"


#include "h.term"
#include "h.serial"


#include "h.vtdef"
#include "h.vtscr"
#include "h.vtcol"
#include "h.vtwimp"
#include "h.vtfile"

#include "h.vtlo"


/*****************************************************************************/

 
void setcolour(int foreground,int background)
{
 front=foreground ^ background;
 back=background;
 front=(front << 24);
 back=(back << 16);
}

void setcolourtext(void)
{
 int fground=physicalcolour(foreground,(style & VTSTREN)>>11);
 int bground=physicalcolour(background,0);

 if(screenmode) setcolour(bground,fground);
 else           setcolour(fground,bground);
}


void setstylec(void)
{
 style=0;
 if(rendition & 0x4)  style=style | VTITAL;
 if(rendition & 0x8)  style=style | VTUNDER;
 if(rendition & 0x30) style=style | VTFLASH;
 if(rendition & 0x3)  style=style | ((rendition & 0x3)<<11);
 if(selerase)         style=style | VTSELER;
 setcolourtext();
}


void setsys(void)
{
 int fground;
 int bground;

 if(screenmode)
 {
  fground=physicalcolour(BLACK,0);
  bground=physicalcolour(WHITE,0);
 }
 else
 {
  fground=physicalcolour(WHITE,0);
  bground=physicalcolour(BLACK,0);
 }

 sfront=fground ^ bground;
 sback=bground;
 sfront=(sfront << 24);
 sback=(sback << 16);
 sstyle=0;
}



void vtlocalcolour(int f,int fs,int b,int bs)
{
 int fground=physicalcolour(f,fs);
 int bground=physicalcolour(b,bs);
 if(screenmode) setcolour(bground,fground);
 else           setcolour(fground,bground);
}



/***************************************************************************/
/* takes scroll buffer coord and maps to data buffer */

int * vtlinebuff(int y)
{
 tline * lp;
 y+=bscroll;
 if(y>=buffsize) y-=buffsize;
 lp=(tline*)(lineindex+sizeof(tline)*y);
 return((int*)(linedata+lp->loc));
}


/* takes scroll buffer coord and maps to index */

tline * vtindex(int y)
{
 tline * lp;
 y+=bscroll;
 if(y>=buffsize) y-=buffsize;
 lp=(tline*)(lineindex+sizeof(tline)*y);
 return(lp);
}


/* takes screen coord and maps to index buffer */

int lineno(int row)
{
 row+=tops+bscroll;
 if(row>=buffsize) row-=buffsize;
 return(row);
}


int attribute(int row)
{
 tline * lp;
 row+=tops+bscroll;
 if(row>=buffsize) row-=buffsize;
 lp=(tline*)(lineindex+sizeof(tline)*row);
 return(lp->attr);
}


void setattribute(int val,int row)
{
 tline * lp;
 row+=tops+bscroll;
 if(row>=buffsize) row-=buffsize;
 lp=(tline*)(lineindex+sizeof(tline)*row);
 lp->attr=val;
}

/*****************************************************************************/
/* mark all chars from xlo to xhi as needing redrawing */

void vtredrawlo(tline * lp,int xlo,int xhi)
{
 if(vtpendsubs) vtclearsub();

 if(lp->rlo==lp->rhi)
 {
  lp->rlo=xlo;
  lp->rhi=xhi+1;
 }
 else
 {
  if(xlo<lp->rlo)  lp->rlo=xlo;
  if(xhi>=lp->rhi) lp->rhi=xhi+1;
 }

 vtpendredraw=1;
}


void vtredraw(int row,int xlo,int xhi)
{
 tline * lp;
 int     y;
 y=lineno(row);
 lp=(tline*)(lineindex+sizeof(tline)*y);
 vtredrawlo(lp,xlo,xhi);
}


/****************************************************************************/

static int vtscforce=0;

void vtsetcursor(int x,int y)
{
 int atrf;

 if(ttyx!=x || ttyy!=y)
 {
  if(!vtmovecurs && vtcurs && vtcursphase) vtredraw(ttyy,ttyx,ttyx);

  if(!vtscforce)
  {
   if(ttyy==24)
   {
    y=24;
   }
   else
   {
    if(y>23) y=23;
   }
  }

  if(y<0)  y=0;
  ttyy=y;

  atrf=attribute(ttyy)>0;
  if(x<0) x=0;
  if(x>=(width>>atrf)) x=(width>>atrf)-1;
  ttyx=x;

  vtmovecurs=1;
 }
}


void vtrefreshcursor(void)
{
 if(!vtmovecurs && vtcurs && vtcursphase)
 {
  vtredraw(ttyy,ttyx,ttyx);
  vtmovecurs=1;
 }
}


void vtsetcursorp(int x,int y)
{
 vtsetcursor(x,y);
 pend=0;
}


/*****************************************************************************/


void setflash(tline * lp,int * data)
{
 int i;

 lp->flo=lp->fhi=0;

 for(i=0;i<width;i++)
 {
  if(data[i] & VTFLASH) 
  {
   lp->flo=i;
   lp->fhi=i+1;
   break;
  }
 }

 while(++i<width)
 {
  if(data[i] & VTFLASH) lp->fhi=i+1;
 }
}



void clearcharslo(tline * lp,int x,int n,int flags)
{
 int   xl=x+n;

 int   loc=lp->loc;
 int * data=(int *)(linedata+loc);
 int   wasflash;
 int   fill;
 int   serase;
 int * dx;


 wasflash=flags & VTWASFLASH;

 serase=flags & VTSELER;
 if(flags &  VTCBACK) fill=front+back+style+SPC;
 else                 fill=sfront+sback+sstyle+SPC;

 dx=data+x;

 while(x<xl)
 {
  if(n<width && ((*dx) & VTFLASH)) wasflash=1;
  if((*dx) & serase)
  {
   dx++;
  }
  else
  {
   *dx++=fill;
  }
  x++;
 }

 if(n==width) lp->flo=lp->fhi=0;
 else
 if(wasflash) setflash(lp,data);
}


void clearchars(int x,int y,int n,int flags)
{
 tline * lp=vtindex(y+tops);
 clearcharslo(lp,x,n,flags);
 vtredrawlo(lp,x,x+n);
}

/* resets an absolute row in the capture buffer */

static void resetrow(int row,int flags)
{
 tline * lp=(tline*)(lineindex+sizeof(tline)*row);
 clearcharslo(lp,0,width,flags);
 lp->attr=0;
}


/* changes the attributes for a line */

void changeattrib(int y,int newatt)
{
 setattribute(newatt,y);
 vtredraw(y,0,width);
}


void writechar(int byte,int x,int y)
{
 tline * lp;
 int     loc;
 int   * data;
 int     wasflash;

 y=lineno(y);
 lp=(tline*)(lineindex+sizeof(tline)*y);
 loc=lp->loc;
 data=(int *)(linedata+loc);

 wasflash=data[x] & VTFLASH;

 byte=front+back+style+byte;
 data[x]=byte;

 if(style & VTFLASH)
 {
  if(x<lp->flo) lp->flo=x;
  if((x+1)>lp->fhi) lp->fhi=x+1;
 }
 else
 if(wasflash) setflash(lp,data);

 vtredrawlo(lp,x,x);
}



void physscroll(int y,int n,int delta)
{
 tline * lp1;
 tline * lp2;
 tline   temp;
 int     y1;
 int     y2;
 int     i;

 if(delta>0)  /* scrolling the screen up - gap appears at bottom */
 {
  y1=lineno(y);
  lp1=((tline*)(lineindex+sizeof(tline)*y1));
  temp=*lp1;

  for(i=1;i<(n+1);i++)
  {
   y2=y1;
   lp2=lp1;
   y1=lineno(y+i);
   lp1=((tline*)(lineindex+sizeof(tline)*y1));
   *lp2=*lp1;
  }

  *lp1=temp;
  lp1->attr=0;
  clearcharslo(lp1,0,width,VTFXNONE);

 }
 else
 if(delta<0)  /* scrolling the screen down - gap appears at top */
 {
  y1=lineno(y+n);
  lp1=((tline*)(lineindex+sizeof(tline)*y1));
  temp=*lp1;

  for(i=n-1;i>=0;i--)
  {
   y2=y1;
   lp2=lp1;
   y1=lineno(y+i);
   lp1=((tline*)(lineindex+sizeof(tline)*y1));
   *lp2=*lp1;
  }

  *lp1=temp;
  lp1->attr=0;
  clearcharslo(lp1,0,width,VTFXNONE);

 }
}






/* swops line 23 with line 24 */

void vtswopstatus(int scrup)
{
 tline * lp1;
 tline * lp2;
 tline   temp;
 int     y1;
 int     y2;

 y1=lineno(23);
 lp1=((tline*)(lineindex+sizeof(tline)*y1));
 temp=*lp1;

 y2=lineno(24);
 lp2=((tline*)(lineindex+sizeof(tline)*y2));

 *lp1=*lp2;
 *lp2=temp;

 if(!scrup)
 {
  lp1->rlo=lp2->rlo=0;
  lp1->rhi=lp2->rhi=width;
 }
}







void scrollblock(int y,int n,int delta)
{
 int scrup;
 int i;
 int limit;


 if(y==0 && n==23)  /* special case, scrolling the whole screen */
 {
  if(vtpendsubs) vtclearsub();

  if(delta>0)
  {
   if(vtheight==25 && ttyy==23)
     scrup=abs((-(24+tops)*TTDY-tscrolly)-(vty0-vty1))<2*TTDY;
   else
     scrup=abs((-(ttyy+tops)*TTDY-tscrolly)-(vty0-vty1))<2*TTDY;

   for(i=0;i<delta;i++)
   {
    if(buffsize-tops==vtheight)             
    {
     resetrow(bscroll,ansisys?VTCBACK:VTFXNONE);
     bscroll++;
     if(bscroll>=buffsize) bscroll=0;
     vtpendshift+=TTDY;
     if(vtheight==25) vtswopstatus(0);
    }
    else
    {
     tops+=1;
     if(scrup)
     {
      tscrolly-=TTDY;
      vtpendscrolly=1;
      vtpendshift+=TTDY;
     }
     if(vtheight==25) vtswopstatus(scrup);
     resetrow(lineno(23),ansisys?VTCBACK:VTFXNONE);
    }
   }
  }
  else
  if(delta<0)
  {
   limit=-delta;
   i=0;
   while(i++<limit)
   {
    physscroll(y,n,-1);
    vtpendshift-=TTDY;
   }
  }
 }
 else
 {  /* just scrolling a bit of the screen */
  if(delta!=0)
  {
   if(vtpendredraw)
   {
    vtdoredraw();
    vtpendredraw=0;
   }

   if(vtpendshift)
   {
    vtscroll(vtpendshift,0);
    vtpendshift=0;
   }

   if(vtpendsubs)
   {
    if(vtsuby==y && vtsubn==n) vtsubdelta+=delta;
    else                       
    {
     vtclearsub();
     vtsuby=y;
     vtsubn=n;
     vtsubdelta=delta;
     vtpendsubs=1;
    }
   }
   else
   {
    vtsuby=y;
    vtsubn=n;
    vtsubdelta=delta;
    vtpendsubs=1;
   }

   i=0;
   if(delta>0)
   {
    while(i++<delta) physscroll(y,n,1);
   }
   else
   {
    limit=-delta;
    while(i++<limit) physscroll(y,n,-1);
   }
  }
 }
}


void scrollrow(int x,int y,int n,int delta)
{
 tline * lp=vtindex(y+tops);
 int     loc=lp->loc;
 int   * data=(int *)(linedata+loc);
 int     m;
 int     wasflash=VTFXNONE;

 if(delta>0)
 {
  m=n;
  while(m--)
  {
   if((data[x+m+delta]=data[x+m]) & VTFLASH) wasflash=VTWASFLASH;
  }
  clearcharslo(lp,x,delta,wasflash);
  vtredrawlo(lp,x,x+n+delta);
 }
 else
 if(delta<0)
 {
  m=-1;
  while(m++<n)
  {
   if((data[x+m+delta]=data[x+m]) & VTFLASH) wasflash=VTWASFLASH;
  }
  clearcharslo(lp,x+n+delta,-delta,wasflash);
  vtredrawlo(lp,x+delta,x+n);
 }
}


/*****************************************************************************/

#define TTYWIDTH width


/* return 0 if not enough memory, else 1 on OK */

int setvtbuffersize(int newsize)
{
 int code;

 if(!newsize && buffsize)
 {
  flex_free((flex_ptr)(&lineindex));
  flex_free((flex_ptr)(&linedata));
  code=1;
 }
 else
 if(!buffsize)
 {
  if(!flex_alloce((flex_ptr)(&lineindex),newsize*sizeof(tline))) return(0);
  code=flex_alloce((flex_ptr)(&linedata),newsize*TTYWIDTH*sizeof(int));
  if(!code)
  {
   flex_free((flex_ptr)(&lineindex));
   return(0);
  }
 }
 else
 {
  if(!flex_extende((flex_ptr)(&lineindex),newsize*sizeof(tline))) return(0);
  code=flex_extende((flex_ptr)(&linedata),newsize*TTYWIDTH*sizeof(int));
  if(!code)
  {
   flex_extend((flex_ptr)(&lineindex),buffsize*sizeof(tline));
   return(0);
  }
 }

 buffsize=newsize;
 return(code);
}



void extendvtbuffer(int at,int by)
{
 tline * lp;
 int     y;

 flex_midextend((flex_ptr)(&lineindex),at*sizeof(tline),by*sizeof(tline));
 flex_midextend((flex_ptr)(&linedata),at*TTYWIDTH*sizeof(int),
                                                  by*TTYWIDTH*sizeof(int));

 for(y=0;y<at;y++)
 {
  lp=(tline*)(lineindex+sizeof(tline)*y);
  if(lp->loc>(at*TTYCOLS*sizeof(int))) 
                         lp->loc+=by*TTYWIDTH*sizeof(int);
 }

 for(y=at+by;y<(buffsize+by);y++)
 {
  lp=(tline*)(lineindex+sizeof(tline)*y);
  if(lp->loc>(at*TTYCOLS*sizeof(int)))
                          lp->loc+=by*TTYWIDTH*sizeof(int);
 }

 buffsize+=by;
}





/* at is the start of the block, by the +ve length */

void shortenvtbuffer(int at,int by)
{
 tline * lp;
 int     loc;
 int     y;


 lp=(tline*)(lineindex+sizeof(tline)*at);
 loc=lp->loc;                             /* location of data to trash */

 flex_midextend((flex_ptr)(&lineindex),(at+by)*sizeof(tline),
                                                       -by*sizeof(tline));
 flex_midextend((flex_ptr)(&linedata),loc+by*TTYWIDTH*sizeof(int),
                                            -by*TTYWIDTH*sizeof(int));

 buffsize-=by;

 for(y=0;y<buffsize;y++)
 {
  lp=(tline*)(lineindex+sizeof(tline)*y);
  if(lp->loc>loc) lp->loc-=by*TTYWIDTH*sizeof(int);
 }
}




static void vtinitline(int y)
{
 tline * lp;

 lp=(tline*)(lineindex+sizeof(tline)*y);
 lp->loc=y*TTYWIDTH*sizeof(int);
 lp->attr=0;
 lp->rlo=0;
 lp->rhi=0;
 lp->flo=0;
 lp->fhi=0;
 clearcharslo(lp,0,width,VTFXNONE); 
}



int bootvtbuffer(void)
{
 int y;
 int code;

 tops=0;
 bscroll=0;

 code=setvtbuffersize(vtdefbuffsize);

 if(!code) return(0);

 for(y=0;y<buffsize;y++) vtinitline(y);

 return(code);
}


void trashvtbuffer(void)
{
 setvtbuffersize(0);
}



/* user enters a new value for vtdefbuffsize */

void vtuserbuffsize(int newsize)
{
 int y;
 int yr;
 int ylo;
 int yhi;
 int refresh=0;
 int oldsize=buffsize;
 int change=newsize-buffsize;
 int at;
 int by;
 tline * lp;
 int ntops;
 int ntscrolly;
 int currentsize;

 if(!change || newsize<25) return;
 else
 if(change>0)  /* increasing buffer size, easy! */
 {
  extendvtbuffer(bscroll,change);
  change=buffsize-oldsize;
  for(y=bscroll;y<(bscroll+change);y++) vtinitline(y);
  tops+=change;
  tscrolly-=change*TTDY;

  if(vtvert)
  {
   extent(whandle[VTVERT],0,-buffsize*TTEDY-80,0,0);
   reopenvertical();
  }
  else
  {


  }
 }
 else                       /* decreasing buffer size, panic */
 {
  /* scan down from end of screen, knocking out lines   */
  /* lines will not be contiguous                       */
  /* tscrolly, and tops will reduce                     */
  /* vertical window extent changes                     */
  /* the vertical scroll bar, must be reopened          */
  /* the window may be open on data which is being trashed */

  yr=tops+vtheight;
  y=bscroll+yr;
  by=0;
  ntops=tops;
  ntscrolly=tscrolly;
  currentsize=buffsize;

  ylo=((vtby-vty1-tscrolly)/TTDY);
  yhi=((vtby-vty0-tscrolly)/TTDY);

  while(change)                   /* nb change is -ve here */
  {
   if(y>=buffsize) 
   {
    y-=buffsize;
    if(by) shortenvtbuffer(at,by);
    if(y>=at) y-=by;
    by=0;
   }

   if(yr>=oldsize) yr-=oldsize;

   lp=(tline*)(lineindex+sizeof(tline)*y);

   if(yr<tops) ntops--;
   if(yr*TTDY<-tscrolly) ntscrolly+=TTDY;
   if(yr>=ylo && yr<=yhi) refresh=1;

   if(!by)
   {
    at=y;
    by=1;
   }
   else
   {
    if(lp->loc!=(at+by)*TTYWIDTH*sizeof(int))
    {
     shortenvtbuffer(at,by);
     if(y>=at) y-=by;
     at=y;
     by=1;
    }
    else
    {
     by++;
    }
   }

   change++;
   currentsize--;

   if(y<bscroll) bscroll--;
   if(bscroll>=currentsize) bscroll=0;

   y++;
   yr++;
  }

  tops=ntops;
  tscrolly=ntscrolly;

/*  dprintf(0,"tops=%d bscroll=%d",tops,bscroll); */

  if(by) shortenvtbuffer(at,by);

  if(vtvert)
  {
   extent(whandle[VTVERT],0,-buffsize*TTEDY-80,0,0);
   reopenvertical();
  }
  else
  {

  }


  if(refresh) refreshwindow(whandle[VTERM]);
 }

 vtdefbuffsize=buffsize;
}



/*****************************************************************************/

void vtclearstatusline(void)
{
 setattribute(0,24);
 clearchars(0,24,width,VTFXNONE);
}


int vtssl(void)
{
 int front;
 int fronts;

 if(!vtopen || vtstatus!=VTSTLOCAL) return(1);

 if(vtvhi) 
 {
  front=CERICE;
  fronts=0;
 }
 else
 {
  front=WHITE;
  fronts=2;
 }

 style=0;
 vtlocalcolour(BLACK,0,front,fronts);

 return(0);
}


char * apstr[2]={"     ","STAT00"};

void vtwriteprint(void)
{
 int    i;
 char * p;

 if(vtssl()) return;

 if(autoprint) p=transtoken(apstr[1]);
 else          p=apstr[0];

 for(i=27;i<32;i++) writechar(p[i-27],i,24);
 setstylec();
}



char * spstr[2]={"     ","STAT01"};

void vtwritespool(void)
{
 int i;
 char * p;

 if(vtssl()) return;

 if(spoolflag) p=transtoken(spstr[1]);
 else          p=spstr[0];

 for(i=34;i<39;i++) writechar(p[i-34],i,24);
 setstylec();
}



char * xpstr[2]={"        ","STAT02"};

void vtwritex(void)
{
 int    i;
 char * p;

 if(vtssl()) return;

 if(flow==2) p=transtoken(xpstr[1]);
 else        p=xpstr[0];

 for(i=41;i<49;i++) writechar(p[i-41],i,24);
 setstylec();
}



void vtwriterates(void)
{
 int i;
 int len;

 if(vtssl()) return;

 len=strlen(ratedisplay);
 for(i=0;i<len;i++) writechar(ratedisplay[i],9+i,24);

 setstylec();
}


void vtwriteleds(void)
{
 int i;

 if(vtssl()) return;

 for(i=0;i<4;i++) writechar(vtleds[i]?0x104:0x109,2+i,24);

 setstylec();
}




void vtwritetime(void)
{
 int i;
 int len;

 if(vtssl()) return;

 len=strlen(onlinetimedisplay);
 for(i=0;i<len;i++) writechar(onlinetimedisplay[i],width-19+i,24);

 setstylec();
}






void vtwritecursorposn(void)
{
 int i;
 char string[12];

 if(vtssl()) return;

 sprintf(string,"%03d,%03d",ttyx+1,ttyy+1);

 for(i=0;i<7;i++) writechar(string[i],width-8+i,24);

 setstylec();
}









void vtwriteonline(void)
{
 int i;
 int len;

 if(vtssl()) return;

 len=strlen(onlinedisplay);
 for(i=0;i<len;i++) writechar(onlinedisplay[i],width-28+i,24);

 setstylec();
}




void vtwritelocalstatus(void)
{
 int i;

 if(vtssl()) return;

 for(i=0;i<width;i++)
 {
  if(i==8 || i==25 || i==(width-10) || i==(width-20) || i==(width-30))
                                                  writechar(0x100+179,i,24);
  else                                            writechar(' ',i,24);
 }

 vtwriteprint();
 vtwritespool();
 vtwritex();
 vtwriteleds();
 vtwriterates();
 vtwritetime();
 vtwriteonline();
 vtwritecursorposn();
}





void vtwritetabsstatus(void)
{
 int i;
 int c;
 int j;
 int k;
 int front;
 int fronts;


 if(vtvhi) 
 {
  front=CERICE;
  fronts=0;
 }
 else
 {
  front=WHITE;
  fronts=2;
 }


 j=1;
 k=0;

 style=0;

 vtlocalcolour(BLACK,0,front,fronts);

 for(i=0;i<width;i++)
 {
  if(j==5) c='|';
  else
  if(j==0) c='0'+k;
  else     c='\'';

  if(tabs[i]) vtlocalcolour(front,fronts,BLACK,0);
  writechar(c,i,24);
  if(tabs[i]) vtlocalcolour(BLACK,0,front,fronts);

  if(++j==10)
  {
   j=0;
   if(++k==10) k=0;
  }
 }

 setstylec();
}




void vtrefreshstatus(void)
{
 if(vtopen)
  switch(vtstatus)
  {
   case VTSTLOCAL:
                  vtwritelocalstatus();
                  break;

   case  VTSTTABS:
                  vtwritetabsstatus();
                  break;
  }
}


void vtrefreshtabs(void)
{
 if(vtstatus==VTSTTABS && vtopen) vtwritetabsstatus();
}



void vtreopen(void)
{
 wimp_wstate winds;
 int         handle;
 int         vertical;

 handle=whandle[VTERM];

 if(vtvert)
 {
  vertical=whandle[VTVERT];
  extent(vertical,0,-buffsize*TTEDY-80,0,0);
  extent(handle,0,-vtheight*TTEDY,width*TTEDX,0);
 }
 else
 {
  extent(handle,0,-buffsize*TTEDY,width*TTEDX,0);
 }


 wimp_get_wind_state(handle,&winds);

 if((winds.o.box.y1-winds.o.box.y0)==24*TTDY)
                               winds.o.box.y0=winds.o.box.y1-vtheight*TTDY;

 vtwimpopenwindows(&winds.o);
}




void vtreopenwidth(int newwidth)
{
 wimp_wstate winds;
 int handle=whandle[VTERM];
 int vertical=whandle[VTVERT];
 int oldwidth;

 oldwidth=width;

 width=newwidth;

 bootvtbuffer();
 createtermsprite();

 tops=buffsize-vtheight;
 tscrolly=-TTDY*tops;
 ttyx=ttyy=0;
 vtselect=0;

 vtrefreshstatus();

 if(vtvert)
 {
  extent(handle,0,-vtheight*TTEDY,width*TTEDX,0);
  extent(vertical,0,-buffsize*TTEDY-80,0,0);
 }
 else
 {
  extent(handle,0,-buffsize*TTEDY,width*TTEDX,0);
 }

 wimp_get_wind_state(handle,&winds);

 if((winds.o.box.x1-winds.o.box.x0)==oldwidth*TTDX)
                               winds.o.box.x1=winds.o.box.x0+width*TTDX;

 vtwimpopenwindows(&winds.o);
 refreshwindow(whandle[VTERM]);
}







/* remove status line */
/* clear status line then reopen */

void vtremstatus(void)
{
 vtheight=24;
 vtclearstatusline();
 vtreopen();
}


/* add status line */

void vtaddstatus(void)
{
 if(buffsize-tops==24)             
 {
  resetrow(bscroll,VTFXNONE);
  bscroll++;
  if(bscroll>=buffsize) bscroll=0;
  tops--;
  tscrolly+=TTDY;
 }

 vtheight=25;
 vtreopen();
}




void vtsetstatusline(int mode)
{
 if(mode==vtstatus) return;

 if(mode==VTSTNONE && vtstatus) vtremstatus();
 else
 if(vtstatus==VTSTNONE && mode) vtaddstatus();

 vtstatus=mode;

 if(vtstatus==VTSTHOST) vtclearstatusline();
 else                   vtrefreshstatus();
}



void vttogglestatus(void)
{
 if(vtstatus) vtsetstatusline(VTSTNONE);
 else         vtsetstatusline(VTSTLOCAL);
}



void vtenterstatusline(void)
{
 if(vtstatus!=VTSTHOST) return;
 if(ttyy!=24) vtdosaveblock(&vtstatusblock);
 vtscforce=1;
 vtsetcursorp(0,24);
 vtscforce=0;
}



void vtexitstatusline(void)
{
 if(ttyy!=24) return;
 vtscforce=1;
 vtdoloadblock(&vtstatusblock);
 vtscforce=0;
}


